{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {},
      "outputs": [],
      "source": [
        "import pod5\n",
        "import argparse\n",
        "import fnmatch\n",
        "import os\n",
        "from deepsignal3.utils import bam_reader\n",
        "import h5py\n",
        "from deepsignal3.utils import fast5_reader\n",
        "import pysam\n",
        "import re\n",
        "from deepsignal3.utils.process_utils import CIGAR_REGEX\n",
        "from deepsignal3.utils.process_utils import CIGAR2CODE\n",
        "def parse_args():\n",
        "    parser = argparse.ArgumentParser()\n",
        "    parser.add_argument('--input_dir', type=str, \n",
        "                        default=\"/home/xiaoyifu/data/HG002/R10.4/20221109_1654_5D_PAG68757_39c39833/pod5_v/\",\n",
        "                        help='the input filepath')\n",
        "    parser.add_argument('--bam', type=str, \n",
        "                        default=\"/home/xiaoyifu/data/HG002/R10.4/20221109_1654_5D_PAG68757_39c39833/bam/example.bam\",\n",
        "                        help='the input filepath')\n",
        "    parser.add_argument('--fast5', type=str, \n",
        "                        default=\"/home/xiaoyifu/data/HG002/R10.4/20221109_1654_5D_PAG68757_39c39833/demo/\",\n",
        "                        help='the input filepath')\n",
        "    parser.add_argument('--w', type=str, \n",
        "                        default=\"/home/xiaoyifu/data/HG002/R10.4/20221109_1654_5D_PAG68757_39c39833/\",\n",
        "                        help='the input filepath')\n",
        "    return parser.parse_args([])\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [],
      "source": [
        "def read_pod5(args,fh):\n",
        "    pod5_dr=pod5.DatasetReader(args.input_dir, recursive=True)\n",
        "    read_ids=pod5_dr.read_ids\n",
        "    #test=[]\n",
        "    for read_id in set(read_ids):\n",
        "        record=pod5_dr.get_read(read_id)\n",
        "        fh.write(str(read_id)+'\\n')\n",
        "        #print(record.read_id)\n",
        "        #test.append(record)\n",
        "        #for record in pod5_dr.get_read(read_id):\n",
        "        #    print(record.read_id)\n",
        "        #    test.append(record)\n",
        "        #    break\n",
        "        #print(record.run_info)\n",
        "        #return read_id\n",
        "    "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [],
      "source": [
        "def _convert_cigarstring2tuple(cigarstr):\n",
        "    # tuple in (oplen, op) format, like 30M -> (30, 0)\n",
        "    return [(int(m[0]), CIGAR2CODE[m[-1]]) for m in CIGAR_REGEX.findall(cigarstr)]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [],
      "source": [
        "def read_bam(bam_index,fh):\n",
        "    pos=0\n",
        "    neg=0\n",
        "    fail=0\n",
        "    for record in bam_index:\n",
        "        fh.write(str(record.query_name)+'\\n')\n",
        "\n",
        "        #strand = \"-\" if record.is_reverse else \"+\"\n",
        "        #if record.cigarstring is None:\n",
        "        #    fail+=1\n",
        "        #    continue\n",
        "        #cigartuple=record.cigartuples#_convert_cigarstring2tuple(record.cigarstring)\n",
        "        #print(cigartuple)\n",
        "        \n",
        "        \n",
        "        #if strand=='+' and cigartuple[-1][-1] == 2:\n",
        "        #    pos+=1\n",
        "            #print(record.cigartuples)\n",
        "            #print(_convert_cigarstring2tuple(record.cigarstring))\n",
        "        #if strand == \"-\" and cigartuple[0][-1] == 2:\n",
        "        #    neg+=1\n",
        "    #print(pos)\n",
        "    #print(neg)\n",
        "    #print(fail)\n",
        "        #print(record.cigartuples)\n",
        "        #print(_convert_cigarstring2tuple(record.cigarstring))\n",
        "        #_convert_cigarstring2tuple(record.cigarstring) is record.cigartuples reverse\n",
        "        #print(record.cigartuples[0][-1])\n",
        "        #print(record.get_cigar_stats())\n",
        "        #print(record.cigarstring)\n",
        "        #print(record.cigartuples)\n",
        "        #print(record.query_sequence)\n",
        "        #a=record.get_cigar_stats()\n",
        "        #break\n",
        "        "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {},
      "outputs": [],
      "source": [
        "def get_files(fast5_dir, is_recursive=True):\n",
        "    fast5_dir = os.path.abspath(fast5_dir)\n",
        "    fast5s = []\n",
        "    if is_recursive:\n",
        "        for root, dirnames, filenames in os.walk(fast5_dir):\n",
        "            for filename in fnmatch.filter(filenames, '*.fast5'):\n",
        "                fast5_path = os.path.join(root, filename)\n",
        "                fast5s.append(fast5_path)\n",
        "    else:\n",
        "        for fast5_name in os.listdir(fast5_dir):\n",
        "            if fast5_name.endswith('.fast5'):\n",
        "                fast5_path = '/'.join([fast5_dir, fast5_name])\n",
        "                fast5s.append(fast5_path)\n",
        "    return fast5s"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {},
      "outputs": [],
      "source": [
        "def read_fast5(fast5s,fh):\n",
        "    for fast5 in fast5s:\n",
        "        multi_f5 = fast5_reader.MultiFast5(fast5)\n",
        "        for readname in iter(multi_f5):\n",
        "            #print(readname)\n",
        "            singlef5 = multi_f5[readname]\n",
        "            fast5read = fast5_reader.SingleFast5(singlef5, is_single=False, )\n",
        "            read_id=readname.replace('read_','')#str(fast5read._read['Raw'].attrs['read_id']).replace('b\\'','').replace('\\'','')\n",
        "            fh.write(read_id+'\\n')\n",
        "            #mapinfo = fast5read.get_map_info('RawGenomeCorrected_000', 'BaseCalled_template')\n",
        "        \n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['mapped_chrom'])\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['mapped_start'])\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['mapped_end'])\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['mapped_strand'])\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs.keys())\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['clipped_bases_start'])\n",
        "            #print(fast5read._read['Analyses']['RawGenomeCorrected_000']['BaseCalled_template']['Alignment'].attrs['clipped_bases_end'])\n",
        "        \n",
        "        #for frag in alignment:\n",
        "        #    print(frag)\n",
        "        #break"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {},
      "outputs": [],
      "source": [
        "if __name__ == '__main__':\n",
        "    args=parse_args()\n",
        "    fh = open(args.w+'read_id_fast5.txt', \"w\", buffering=512)\n",
        "    fast5=get_files(args.fast5, is_recursive=True)\n",
        "    read_fast5(fast5,fh)\n",
        "    #read_pod5(args,fh)\n",
        "    #bam_index=pysam.AlignmentFile(args.bam)\n",
        "    #read_bam(bam_index,fh)\n",
        "    #a=None\n",
        "    #read_ids=['197b8704-75bb-491f-b7ea-1c3065abda1b']\n",
        "    \n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Cigars: [(4, 31), (0, 352), (1, 1), (0, 282), (2, 1), (0, 12), (4, 2)]\n",
            "Chrom Strands: ('chr21', '+')\n",
            "Frags: (31, 678, 33912311, 33912958)\n"
          ]
        }
      ],
      "source": [
        "data = [([(4, 31), (0, 352), (1, 1), (0, 282), (2, 1), (0, 12), (4, 2)], ('chr21', '+'), (31, 678, 33912311, 33912958))]\n",
        "\n",
        "# Unpack the values\n",
        "cigars, chrom_strands, frags = data[0]\n",
        "\n",
        "# Now you can use the variables\n",
        "print(\"Cigars:\", cigars)\n",
        "print(\"Chrom Strands:\", chrom_strands)\n",
        "print(\"Frags:\", frags)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "2"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "cigars[-1][-1]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {},
      "outputs": [],
      "source": [
        "item_chrom, item_strand=chrom_strands"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Axes: ylabel='Density'>"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import seaborn as sns\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "# 你的数组，包含不等长的子列表\n",
        "data = [[1, 2, 3],\n",
        "        [4, 5],\n",
        "        [6, 7, 8, 9],\n",
        "        [10, 11, 12, 13, 14]]\n",
        "\n",
        "# 获取每个子列表的长度\n",
        "lengths = [len(sublist) for sublist in data]\n",
        "\n",
        "# 绘制密度图\n",
        "sns.kdeplot(lengths, fill=True, cut=0)\n",
        "#plt.xlabel('Length of Sublists')\n",
        "#plt.ylabel('Density')\n",
        "#plt.title('Density Plot of Sublist Lengths')\n",
        "#plt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "deepsignalpenv",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.17"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
